package com.ruoyi.zhongchuangauto.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.google.common.collect.Lists;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.zhongchuangauto.domain.OrderMaster;
import com.ruoyi.zhongchuangauto.domain.Product;
import com.ruoyi.zhongchuangauto.mapper.ProductMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.zhongchuangauto.mapper.SplitOrderMapper;
import com.ruoyi.zhongchuangauto.domain.SplitOrder;
import com.ruoyi.zhongchuangauto.service.ISplitOrderService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 待分单订单Service业务层处理
 *
 * @author ruoyi
 * @date 2025-09-19
 */
@Service
@DataSource(DataSourceType.ZHONGCHUANGAUTO)
public class SplitOrderServiceImpl implements ISplitOrderService
{
    @Autowired
    private SplitOrderMapper splitOrderMapper;
    @Autowired
    private RuoYiConfig ruoyiConfig;   // 直接注入
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    @Autowired
    private ProductMapper productMapper;

    /**
     * 查询待分单订单
     *
     * @param orderId 待分单订单主键
     * @return 待分单订单
     */
    @Override
    public SplitOrder selectSplitOrderByOrderId(Long orderId)
    {
        return splitOrderMapper.selectSplitOrderByOrderId(orderId);
    }

    /**
     * 查询待分单订单列表
     *
     * @param splitOrder 待分单订单
     * @return 待分单订单
     */
    @Override
    public List<SplitOrder> selectSplitOrderList(SplitOrder splitOrder)
    {
        return splitOrderMapper.selectSplitOrderList(splitOrder);
    }

    /**
     * 新增待分单订单
     *
     * @param splitOrder 待分单订单
     * @return 结果
     */
    @Override
    public int insertSplitOrder(SplitOrder splitOrder)
    {
        splitOrder.setCreateTime(DateUtils.getNowDate());
        return splitOrderMapper.insertSplitOrder(splitOrder);
    }

    /**
     * 修改待分单订单
     *
     * @param splitOrder 待分单订单
     * @return 结果
     */
    @Override
    public int updateSplitOrder(SplitOrder splitOrder)
    {
        splitOrder.setUpdateTime(DateUtils.getNowDate());
        return splitOrderMapper.updateSplitOrder(splitOrder);
    }

    /**
     * 批量删除待分单订单
     *
     * @param orderIds 需要删除的待分单订单主键
     * @return 结果
     */
    @Override
    public int deleteSplitOrderByOrderIds(Long[] orderIds)
    {
        return splitOrderMapper.deleteSplitOrderByOrderIds(orderIds);
    }

    /**
     * 删除待分单订单信息
     *
     * @param orderId 待分单订单主键
     * @return 结果
     */
    @Override
    public int deleteSplitOrderByOrderId(Long orderId)
    {
        return splitOrderMapper.deleteSplitOrderByOrderId(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String  uploadZcsplit(String fileUrl){
        // 1. 把 url 转成本地文件路径
        String localPath = ruoyiConfig.getProfile() + StringUtils.substringAfter(fileUrl, Constants.RESOURCE_PREFIX);
        File file = new File(localPath);
        if (!file.exists()) throw new ServiceException("文件不存在");
        List<SplitOrder> list= new ArrayList<>();
        // 2. 用 EasyExcel 读取（内存友好）
        try (InputStream in = new FileInputStream(localPath)) {
            list= EasyExcel.read(in)
                    .head(SplitOrder.class)   // 建一个实体类映射列
                    .sheet()
                    .doReadSync();
        }catch (Exception e){
        }
        if (CollUtil.isEmpty(list)){
            throw new ServiceException("Excel 无数据");
        }else{
            //进行数据分单处理
           return  handleLargeList(list);
        }
    }
        public String handleLargeList(List<SplitOrder> sourceList) {
            int insetNum=0;
            int batchSize = 100;// 每批 100条
            List<List<SplitOrder>> parts = Lists.partition(sourceList, batchSize);
            List<String> errorTipsList = new ArrayList<>();
            for (List<SplitOrder> batch : parts) {
                /* 1. 开 BATCH 会话，手动控制事务 */
                try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
                    /* 2. 批量查询并把结果写回当前 batch */
                    List<Product> products = productMapper.queryMerchantByProductNameSpec(batch);
                    //判断获取商家邮箱的数量是否跟查询的订单数量相同，如果不同 则直接返回错误
                    if (CollUtil.isEmpty(products)){
                        throw new ServiceException("未查询到订单数据对应的商家和商家邮箱数据");
                    }

                    // 1. 建 Map 时保持统一规则：spec == null 当 ""
                    Map<String, Product> map = products.stream()
                            .collect(Collectors.toMap(
                                    p -> p.getProductName() + "\001" + StringUtils.defaultString(p.getSpec()),
                                    Function.identity(),
                                    (a, b) -> a));          // 重复留第一条

                    // 2. 批处理也用同样规则
                    batch.forEach(o -> {
                        String key = o.getProductName() + "\001" + StringUtils.defaultString(o.getSpecInfo());
                        Product p = map.get(key);

                        if (p == null || StringUtils.isBlank(p.getMerchantEmail())) {
                            // 未匹配 或 邮箱为空 都记为错误
                            errorTipsList.add(String.format("订单编号：%s 商品名称：%s 未获取到对应的商家和商家邮箱信息",
                                    o.getOrderNo(), o.getProductName()));
                        } else {
                            o.setProductCode(p.getProductCode());
                            o.setMerchantName(p.getMerchantName());
                            o.setMerchantEmail(p.getMerchantEmail());
                            o.setCreateTime(new Date());
                            o.setUpdateTime(new Date());
                        }
                    });

                    /* 3. 批量插入 */
                    int c=splitOrderMapper.insertSplitOrderBatch(batch);
                    insetNum+=c;//将插入成功的条数添加给insetNum
                    session.commit();   // 每 100 条一次事务
                }catch(Exception e){
                    throw new ServiceException("分单查询商家邮箱时出错"+e.getMessage());
                }
            }

            //判断插入数据库中得条数跟传递过来的条数是否一致
            if(sourceList.size()==insetNum){
                return "插入数据库共"+insetNum+"条数据成功";
            }else{
                errorTipsList.add("插入数据库条数："+insetNum+"条，跟上传得条数："+sourceList.size()+"条数不一致，请查找原因");
                return String.join("；\n", errorTipsList);
            }
        }
}
